/*
 * endstops.h
 *
 * Copyright 2011 Pieter Agten
 *
 * This file is part of Yarf.
 *
 * Yarf is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Yarf is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Yarf.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @file   endstops.h
 * @author Pieter Agten (pieter.agten@gmail.com)
 * @date   22 sep 2011
 * @brief  Implements checking the status of the endstop switches.
 */

#ifndef ENDSTOPS_H
#define ENDSTOPS_H

#include "yarf.h"
#include "fastio.h"

#include <stdbool.h>

/**
 * Returns whether the x min endstop is pressed.
 */
#define endstop_x_min() (READ(X_MIN_PIN) != X_MIN_ENDSTOP_INVERTED)
/**
 * Returns whether the y min endstop is pressed.
 */
#define endstop_y_min() (READ(Y_MIN_PIN) != Y_MIN_ENDSTOP_INVERTED)
/**
 * Returns whether the z min endstop is pressed.
 */
#define endstop_z_min() (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTED)

/**
 * Returns whether the x max endstop is pressed, if such an endstop is
 * available. Returns false otherwise.
 */
#if (SOFTWARE_MAX_ENDSTOPS || X_MAX_PIN == -1)
#define endstop_x_max() (false)
#else
#define endstop_x_max() (READ(X_MAX_PIN) != X_MAX_ENDSTOP_INVERTED)
#endif

/**
 * Returns whether the y max endstop is pressed, if such an endstop is
 * available. Returns false otherwise.
 */
#if (SOFTWARE_MAX_ENDSTOPS || Y_MAX_PIN == -1)
#define endstop_y_max() (false)
#else
#define endstop_y_max() (READ(Y_MAX_PIN) != Y_MAX_ENDSTOP_INVERTED)
#endif


/**
 * Returns whether the z max endstop is pressed, if such an endstop is
 * available. Returns false otherwise.
 */
#if (SOFTWARE_MAX_ENDSTOPS || Z_MAX_PIN == -1)
#define endstop_z_max() (false)
#else
#define endstop_z_max() (READ(Z_MAX_PIN) != Z_MAX_ENDSTOP_INVERTED)
#endif


/**
 * Returns whether a specific min endstop is pressed.
 *
 * @param axis the axis for which to check the min endstop
 * @return whether the specified min endstop is pressed
 */
static inline bool
endstop_min(unsigned char axis) {
  switch(axis) {
    case X_AXIS:
      return endstop_x_min();
    case Y_AXIS:
      return endstop_y_min();
    case Z_AXIS:
      return endstop_z_min();
    case E_AXIS:
      return false;
    default:
      return true;
  }
}

/**
 * Returns whether a specific max endstop is pressed.
 *
 * @param axis the axis for which to check the max endstop
 * @return whether the specified max endstop is pressed or false if the
 *         specified max endstop is not available.
 */
static inline bool
endstop_max(unsigned char axis) {
  switch(axis) {
    case X_AXIS:
      return endstop_x_max();
    case Y_AXIS:
      return endstop_y_max();
    case Z_AXIS:
      return endstop_z_max();
    case E_AXIS:
      return false;
    default:
      return true;
  }
}

#endif //ENDSTOPS_H
